using System;
using System.ComponentModel;
using Emgu.CV;
using Emgu.CV.Structure;
using NIPO.Data;
using NIPO.Plugins;
using NIPO.Util;

namespace NIPOCvPlugins.FileOutputPlugin
{
    public class VideoFileOutputPlugin : OutputPlugin
    {
        private VideoWriter _writer;
        private VideoFileOutputPluginConfiguration _config = new VideoFileOutputPluginConfiguration() { FPS = 25 };


        #region Overrides of Plugin
        public override PluginConfiguration ConfigurationObject
        {
            get
            {
                return _config;
            }
            set
            {
                _config = (VideoFileOutputPluginConfiguration)value;
            }
        }
        protected override void Initialize()
        {
            _writer = new VideoWriter(_config.FilePath, VideoFileOutputPluginConfiguration.ToFOURCC(_config.FOURCC), _config.FPS, _config.Width, _config.Height, _config.IsColor);
        }

        public override void Dispose()
        {
            _writer.Dispose();
        }

        public override bool IsConfigured
        {
            get { return !string.IsNullOrEmpty(_config.FilePath); }
        }

        public override void Reset()
        {
            _writer.Dispose();
            Initialize();
        }

        public override void OutputData(object sender, NIPOEventArgs e)
        {
            if (!_config.IsColor)
            {
                if (e.Data is GenericDTO<Image<Gray, byte>>)
                {
                    _writer.WriteFrame((e.Data as GenericDTO<Image<Gray, byte>>).Value);
                }
            }
            else
            {
                _writer.WriteFrame((e.Data as GenericDTO<Image<Bgr, byte>>).Value);
            }
        }

        #endregion
    }


    [Serializable]
    public class VideoFileOutputPluginConfiguration : PluginConfiguration
    {
        [Editor(typeof(System.Windows.Forms.Design.FileNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
        public string FilePath
        {
            get;
            set;
        }

        public int FPS
        { get; set; }

        public int Width { get; set; }
        public int Height { get; set; }
        public char[] FOURCC
        {
            get;
            set;
        }


        internal static int ToFOURCC(char[] codec)
        {
            if (codec.Length < 4)
                return -1;

            char c1 = codec[0];
            char c2 = codec[1];
            char c3 = codec[2];
            char c4 = codec[3];
            return (((c1) & 255) + (((c2) & 255) << 8) + (((c3) & 255) << 16) + (((c4) & 255) << 24));
        }

        public bool IsColor
        { get; set; }
    }
}